package com.grouplay.service.impl;

import com.grouplay.dao.IGroupDao;
import com.grouplay.dao.IInvitationDao;
import com.grouplay.dao.IUserDao;
import com.grouplay.dao.IUserGroupDao;
import com.grouplay.entity.Group;
import com.grouplay.entity.GroupBudget;
import com.grouplay.entity.Invitation;
import com.grouplay.entity.User;
import com.grouplay.service.IGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service("groupService")
public class GroupServiceImpl implements IGroupService {
    @Autowired
    private IGroupDao groupDao;
    @Autowired
    private IUserDao userDao;
    @Autowired
    private IUserGroupDao userGroupDao;
    @Autowired
    private IInvitationDao invitationDao;

    @Override
    public boolean createGroup(User user, Group group) {
        // 查找是否有未结束的相同名字的团队
        if (groupDao.findGroupsByGroupName(group.getGroupName()) != null){
            return false;
        }
        group.setLeaderId(user.getId());
        group.setIsEnd(0);
        groupDao.insert(group);
        return true;
    }

    @Override
    public List<Group> findAllGroupsByLeaderId(Integer leaderId) {
        return groupDao.findAllGroupsByLeaderId(leaderId);
    }

    @Override
    public List<Group> findNotEndGroupsByLeaderId(Integer leaderId) {
        return groupDao.findNotEndGroupsByLeaderId(leaderId);
    }

    @Override
    public List<Group> findIsEndGroupsByLeaderId(Integer leaderId) {
        return groupDao.findIsEndGroupsByLeaderId(leaderId);
    }

    @Override
    public List<User> findAllUserNameOfTheGroupByGroupWhileIsNotEnd(Integer groupId, Integer leaderId) {
        Group group = new Group();
        group.setId(groupId);
        group.setLeaderId(leaderId);
        return groupDao.findAllUserNameOfTheGroupByGroupWhileIsNotEnd(group);
    }

    @Override
    public boolean sendOneInvitation(Integer groupId, String targetName, Integer leaderId) {
        Group group = groupDao.findGroupById(groupId);
        if (group == null && group.getLeaderId() != leaderId && group.getIsEnd() == 1) {
            return false;
        }
        User targetUser = userDao.findUserByName(targetName);
        if (targetUser == null || targetUser.getId() == leaderId) {
            return false;
        }
        Group g = new Group();
        g.setId(groupId);
        g.setLeaderId(targetUser.getId());
        if (userGroupDao.userIsInGroup(g) > 0){
            return false;
        }
        Invitation invitation = new Invitation();
        invitation.setGroupId(groupId);
        invitation.setTargetUid(targetUser.getId());
        invitation.setHasBeenLooked(1);
        invitationDao.updateInvitation(invitation);
        invitation.setDate(new Date());
        invitation.setHasBeenLooked(0);
        groupDao.sendOneInvitation(invitation);
        return true;
    }

    @Override
    public Group findGroupByGroupIdAndUid(Integer groupId, Integer uid) {
        Invitation invitation = new Invitation();
        invitation.setTargetUid(uid);
        invitation.setGroupId(groupId);
        if (invitationDao.findCountInviteMe(invitation) != 1) {
            return null;
        }
        Group group = groupDao.findGroupById(groupId);
        if (group == null) {
            return null;
        }
        group.setNumberOfMembers(userGroupDao.findNumberOfMembersByGroupId(groupId));
        return group;
    }

    @Override
    public boolean joinInGroupByGroupIdAndUid(Integer groupId, Integer uid) {
        Invitation invitation = new Invitation();
        invitation.setTargetUid(uid);
        invitation.setGroupId(groupId);
        if (invitationDao.findCountInviteMe(invitation) != 1) {
            return false;
        }
        Group group = groupDao.findGroupById(groupId);
        if (group == null) {
            return false;
        }
        invitation.setHasBeenLooked(1);
        invitationDao.updateInvitation(invitation);
        userGroupDao.joinInGroupByInvitation(invitation);
        return true;
    }

    @Override
    public boolean updateGroupBudget(Group group) {
        Group g = groupDao.findGroupById(group.getId());
        if (g == null && g.getLeaderId() != group.getLeaderId() && g.getIsEnd() == 1){
            return false;
        }
        if (g.getBeginTime().getTime() - (new Date()).getTime() < 12 * 60 * 60 * 1000){
            return false;
        }
        groupDao.updateGroupBudget(group);
        return true;
    }

    @Override
    public List<Group> findMyJoinGroupsByUid(Integer uid) {
        List<Group> groups = groupDao.findMyJoinGroupsByUid(uid);
        for (Group group : groups) {
            group.setNumberOfMembers(userGroupDao.findNumberOfMembersByGroupId(group.getId()));
        }
        return groups;
    }

    @Override
    public boolean endGroup(Integer groupId, Integer leaderId) {
        Group group = groupDao.findGroupById(groupId);
        if (group == null || group.getLeaderId() != leaderId || group.getIsEnd() == 1) {
            return false;
        }
        group.setEndTime(new Date());
        groupDao.endGroup(group);
        return true;
    }

    @Override
    public List<Group> findMyJoinGroupsIsEndAndIsNotPay(Integer uid) {
        List<Group> groups = groupDao.findMyJoinGroupsIsEndAndIsNotPay(uid);
        for (Group group : groups) {
            group.setNumberOfMembers(userGroupDao.findNumberOfMembersByGroupId(group.getId()));
            group.setNeedMoney((group.getTotalBudget() - group.getPersonalBudget()) / (group.getNumberOfMembers() - 1));
        }
        return groups;
    }

    @Override
    public List<GroupBudget> findGroupBudgetByGroupId(Integer groupId, Integer uid) {
        Group group = groupDao.findGroupById(groupId);
        if (group == null || group.getIsEnd() == 0) {
            return new ArrayList<>();
        }
        Group g = new Group();
        g.setId(groupId);
        g.setLeaderId(uid);
        if (group.getLeaderId() != uid && userGroupDao.userIsInGroup(g) != 1) {
            return new ArrayList<>();
        }
        List<GroupBudget> groupBudgets = groupDao.findGroupBudgetByGroupId(groupId);
        for (int i = 0; i < groupBudgets.size(); i ++) {
            groupBudgets.get(i).setTotalMoney(group.getTotalBudget());
        }
        GroupBudget groupBudget = new GroupBudget();
        groupBudget.setGroupName(group.getGroupName());
        groupBudget.setIsLeader(1);
        groupBudget.setPayer(group.getLeaderName());
        groupBudget.setPayMoney(group.getPersonalBudget());
        groupBudget.setTotalMoney(group.getTotalBudget());
        groupBudgets.add(groupBudget);
        return groupBudgets;
    }
}
